package com.ruoyi.framework.task;

import com.ruoyi.project.ins.api.InsApi;
import com.ruoyi.project.ins.domain.InsAccount;
import com.ruoyi.project.ins.domain.InsWebProxy;
import com.ruoyi.project.ins.domain.InstagramAccount;
import com.ruoyi.project.ins.service.IInsAccountService;
import com.ruoyi.project.ins.service.IInsWebProxyService;
import com.ruoyi.project.ins.utils.TaskUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Slf4j
@Component("insCheckAliveTask")
public class InsCheckAliveTask {
    @Autowired
    private IInsAccountService insAccountService;

    // 注入线程池 Bean
    @Qualifier("asyncTaskExecutor")
    @Autowired
    private Executor asyncTaskExecutor;

    @Autowired
    private IInsWebProxyService insWebProxyService;

    private final List<InsAccount> needUpdateList = Collections.synchronizedList(new ArrayList<>());

    public void run() {
        try {
            log.info("ins定时检测账号存活任务开始执行");
            List<InsAccount> insAccountList = insAccountService.selectNeedCheckAccount();
            if (CollectionUtils.isEmpty(insAccountList)) {
                log.info("无需要获取检测的用户，任务退出");
                return;
            }
            InsWebProxy insWebProxyParam = new InsWebProxy();
            insWebProxyParam.setStatus("0");
            List<InsWebProxy> insWebProxyList = insWebProxyService.selectInsWebProxyList(insWebProxyParam);
            if (CollectionUtils.isEmpty(insWebProxyList)) {
                log.info("无网络代理配置信息，任务退出");
                return;
            }

            long startTime = System.currentTimeMillis();
            // 按创建人分组，每组一个线程安全队列
            Map<String, List<InsWebProxy>> insWebProxyMap = insWebProxyList.stream()
                .filter(item -> StringUtils.isNotBlank(item.getSysUsername()))
                .collect(Collectors.groupingBy(InsWebProxy::getSysUsername));

            // 2️⃣ 批次并发
            List<CompletableFuture<Void>> futures = new ArrayList<>();
            int batchSize = TaskUtils.getBatchSize(insAccountList.size());
            log.info("每组执行的任务数: {}", batchSize);
            int groupIndex = 1;
            AtomicInteger counter = new AtomicInteger(1);
            for (int i = 0; i < insAccountList.size(); i += batchSize) {
                int end = Math.min(i + batchSize, insAccountList.size());
                List<InsAccount> batchList = new ArrayList<>(insAccountList.subList(i, end));
                log.info("即将启动检测账号任务第{}组", groupIndex ++);
                // 每一批交给线程池的一个任务去串行处理
                CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                    for (InsAccount insAccount : batchList) {
                        log.info("检测账号任务正在处理第{}条", counter.getAndIncrement());
                        String username = insAccount.getCreateBy();
                        if (!insWebProxyMap.containsKey(username)) {
                            log.info("无对应网络代理信息，检测存活跳过账号userId：{}，创建者：{}", insAccount.getUserId(), username);
                            return;
                        }
                        InsWebProxy insWebProxy = insWebProxyMap.get(username).get(0);
                        checkAccount(insAccount, insWebProxy);
                    }
                }, asyncTaskExecutor);
                // 保存 future，以便后面等待全部完成
                futures.add(future);
            }
            // 等待所有异步任务完成
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
            // 执行批量更新
            batchUpdateAccounts();
            log.info("ins定时检测账号存活任务执行结束, 耗时: {}s", (System.currentTimeMillis() - startTime) / 1000);
        } catch (Exception e) {
            log.info("ins定时检测账号存活任务异常中断, e: {}", e.getMessage());
        }
    }

    private void batchUpdateAccounts() {
        synchronized (needUpdateList) {
            if (!CollectionUtils.isEmpty(needUpdateList)) {
                log.info("批量更新账号数量: {}", needUpdateList.size());
                insAccountService.batchUpdateInsAccount(needUpdateList);
                needUpdateList.clear();
            }
        }
    }

    // 单独处理一个账号的方法
    private void checkAccount(InsAccount insAccount, InsWebProxy proxy) {
        log.info("开始检测账号 [{}] 存活状态", insAccount.getUsername());
        InstagramAccount account = InstagramAccount.builder()
            .username(insAccount.getUsername()).userId(insAccount.getUserId()).bearerToken(insAccount.getAuth())
            .rur(insAccount.getRur()).wwwClaim(insAccount.getClaim()).mid(insAccount.getMid())
            .build();
        proxy.setCountryCode(insAccount.getCountryCode());
        Boolean accountAlive = InsApi.checkAccountAlive(account, proxy);
        if (accountAlive == null) {
            log.info("检测账号 [{}] 失败：接口无响应或超时", insAccount.getUsername());
            insAccount.setCheckResult("未知状态");
            insAccount.setCheckTime(new Date());
            needUpdateList.add(insAccount);
            return;
        } else if (accountAlive) {
            log.info("检测结果：账号 [{}] 仍然存活", insAccount.getUsername());
            insAccount.setStatus("0");
            insAccount.setCheckTime(new Date());
            insAccount.setCheckResult("账号存活");
        } else {
            log.info("检测结果：账号 [{}] 已被封", insAccount.getUsername());
            insAccount.setStatus("1");
            insAccount.setCheckTime(new Date());
            insAccount.setCheckResult("账号被封");
        }
        needUpdateList.add(insAccount);
    }
}
